#include "iic.h"

/**
 * @brief i2c引脚初始化
 * @param IIC通道
 * @note 使用软件IIC，硬件IIC下次一定
 */
void IIC_Init(u8 IIC)
{
    GPIO_InitTypeDef  GPIO_InitStructure;

    if(IIC == IIC1)
        RCC_AHB1PeriphClockCmd(RCC_I2C1, ENABLE);
    else if(IIC == IIC2)
        RCC_AHB1PeriphClockCmd(RCC_I2C2, ENABLE);

    GPIO_InitStructure.GPIO_Mode    = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_Speed   = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_OType   = GPIO_OType_OD;
    GPIO_InitStructure.GPIO_PuPd    = GPIO_PuPd_UP;

    if(IIC == IIC1)
    {
        GPIO_InitStructure.GPIO_Pin     = I2C1_Pin_SCL|I2C1_Pin_SDA;
        GPIO_Init(I2C1_PORT, &GPIO_InitStructure);
    }
    else if(IIC == IIC2)
    {
        GPIO_InitStructure.GPIO_Pin     = I2C2_Pin_SCL|I2C2_Pin_SDA;
        GPIO_Init(I2C2_PORT, &GPIO_InitStructure);
    } 
}


void I2C_Delay(void)
{
    __nop();
    __nop();
    __nop();
    __nop();
    __nop();
    __nop();
    __nop();
    __nop();
    __nop();

    if(Fast_I2C)
    {
        u8 i = 15;
        while(i--);
    }
}

/**
 * @brief i2c发送初始信号
 * @param IIC通道
 * @return  1:总线接入
 *          0:总线接入失败
 */
int I2C_Start(u8 IIC)
{
    if(IIC == IIC1)
    {
        SDA1_H;
        SCL1_H;
        I2C_Delay();
        if(!SDA1_read)return 0;	//SDA线为低电平则总线忙,退出
        SDA1_L;
        I2C_Delay();
        if(SDA1_read) return 0;	//SDA线为高电平则总线出错,退出
        SDA1_L;
        I2C_Delay();
    }
    else if(IIC == IIC2)
    {
        SDA2_H;
        SCL2_H;
        I2C_Delay();
        if(!SDA2_read)return 0;	//SDA线为低电平则总线忙,退出
        SDA2_L;
        I2C_Delay();
        if(SDA2_read) return 0;	//SDA线为高电平则总线出错,退出
        SDA2_L;
        I2C_Delay();
    }
    return 1;
}

void I2C_Stop(u8 IIC)
{
    if(IIC == IIC1)
    {
        SCL1_L;
        I2C_Delay();
        SDA1_L;
        I2C_Delay();
        SCL1_H;
        I2C_Delay();
        SDA1_H;
        I2C_Delay();
    }
    else if(IIC == IIC2)
    {
        SCL2_L;
        I2C_Delay();
        SDA2_L;
        I2C_Delay();
        SCL2_H;
        I2C_Delay();
        SDA2_H;
        I2C_Delay();
    }
}


/**
 * @brief i2c应答
 * @param IIC通道 是否应答
 */ 
void I2C_Ack(u8 IIC,u8 Mod)
{
    if(IIC == IIC1)
    {
        SCL1_L;
        I2C_Delay();

        if(Mod == YES)
            SDA1_L;
        else if(Mod == NO)
            SDA1_H;

        I2C_Delay();
        SCL1_H;
        I2C_Delay();
        SCL1_L;
        I2C_Delay();
    }
    else if(IIC == IIC2)
    {
        SCL2_L;
        I2C_Delay();

        if(Mod == YES)
            SDA2_L;
        else if(Mod == NO)
            SDA2_H;

        I2C_Delay();
        SCL2_H;
        I2C_Delay();
        SCL2_L;
        I2C_Delay();
    }

}

/**
 * @brief i2c等待ACK应答
 * @param IIC通道
 * @return  1:有ACK
 *          0:无ACK
 */
int I2C_WaitAck(u8 IIC)
{
    if(IIC == IIC1)
    {
        SCL1_L;
        I2C_Delay();
        SDA1_H;
        I2C_Delay();
        SCL1_H;
        I2C_Delay();
        if(SDA1_read)
        {
            SCL1_L;
            I2C_Delay();
            return 0;
        }
        SCL1_L;
    }
    else if(IIC == IIC2)
    {
        SCL2_L;
        I2C_Delay();
        SDA2_H;
        I2C_Delay();
        SCL2_H;
        I2C_Delay();
        if(SDA2_read)
        {
            SCL2_L;
            I2C_Delay();
            return 0;
        }
        SCL2_L;
    }
    I2C_Delay();
    return 1;
}

/**
 * @brief   i2c发送信号
 * @param   IIC通道 发送数据
 */
void I2C_SendByte(u8 IIC,u8 SendByte)
{
    u8 i=8;
    if(IIC == IIC1)
    {
        while(i--)
        {
            SCL1_L;
            I2C_Delay();
            if(SendByte&0x80)
                SDA1_H;
            else
                SDA1_L;
            SendByte<<=1;
            I2C_Delay();
            SCL1_H;
            I2C_Delay();
        }
        SCL1_L;
    }
    else if(IIC == IIC2)
    {
        while(i--)
        {
            SCL2_L;
            I2C_Delay();
            if(SendByte&0x80)
                SDA2_H;
            else
                SDA2_L;
            SendByte<<=1;
            I2C_Delay();
            SCL2_H;
            I2C_Delay();
        }
        SCL2_L;
    }
}

/**
 * @brief   i2c读入信号
 * @param   IIC通道
 * @return  i2c接收位
 * @note    数据从高位到低位
 */
u8 I2C_ReadByte(u8 IIC)
{
    u8 i=8;
    u8 ReceiveByte=0;

    if (IIC == IIC1)
    {
        SDA1_H;
        while(i--)
        {
            ReceiveByte<<=1;
            SCL1_L;
            I2C_Delay();
            SCL1_H;
            I2C_Delay();
            if(SDA1_read)
                ReceiveByte|=0x01;
        }
        SCL1_L;
    }
    else if (IIC == IIC2)
    {
        SDA2_H;
        while(i--)
        {
            ReceiveByte<<=1;
            SCL2_L;
            I2C_Delay();
            SCL2_H;
            I2C_Delay();
            if(SDA2_read)
                ReceiveByte|=0x01;
        }
        SCL2_L;
    }
    return ReceiveByte;
}



//单字节写入
int I2C1_Single_Write(u8 SlaveAddress,u8 REG_Address,u8 REG_data)
{
    if(!I2C_Start(IIC1))return 0;
    I2C_SendByte(IIC1,SlaveAddress);   //发送设备地址+写信号//I2C_SendByte(((REG_Address & 0x0700) >>7) | SlaveAddress & 0xFFFE);//设置高起始地址+器件地址
    if(!I2C_WaitAck(IIC1)) {
        I2C_Stop(IIC1);
        return 0;
    }
    I2C_SendByte(IIC1,REG_Address );   //设置低起始地址
    I2C_WaitAck(IIC1);
    I2C_SendByte(IIC1,REG_data);
    I2C_WaitAck(IIC1);
    I2C_Stop(IIC1);
    return 1;
}

//单字节读取
int I2C1_Single_Read(u8 SlaveAddress,u8 REG_Address)
{
    unsigned char REG_data;
    if(!I2C_Start(IIC1))return 0;
    I2C_SendByte(IIC1,SlaveAddress); //I2C_SendByte(((REG_Address & 0x0700) >>7) | REG_Address & 0xFFFE);//设置高起始地址+器件地址
    if(!I2C_WaitAck(IIC1))
    {
        I2C_Stop(IIC1);
        return 0;
    }
    I2C_SendByte(IIC1,(u8) REG_Address);   //设置低起始地址
    I2C_WaitAck(IIC1);
    I2C_Start(IIC1);
    I2C_SendByte(IIC1,SlaveAddress+1);
    I2C_WaitAck(IIC1);

    REG_data= I2C_ReadByte(IIC1);
    I2C_Ack(IIC1,NO);
    I2C_Stop(IIC1);
    return REG_data;
}

//多字节读取
int I2C1_Mult_Read(u8 SlaveAddress,u8 REG_Address,u8 * ptChar,u8 size)
{
    uint8_t i;

    if(size < 1)
        return 0;
    if(!I2C_Start(IIC1))
        return 0;
    I2C_SendByte(IIC1,SlaveAddress);
    if(!I2C_WaitAck(IIC1))
    {
        I2C_Stop(IIC1);
        return 0;
    }
    I2C_SendByte(IIC1,REG_Address);
    I2C_WaitAck(IIC1);

    I2C_Start(IIC1);
    I2C_SendByte(IIC1,SlaveAddress+1);
    I2C_WaitAck(IIC1);

    for(i=1; i<size; i++)
    {
        *ptChar++ = I2C_ReadByte(IIC1);
        I2C_Ack(IIC1,YES);
    }
    *ptChar++ = I2C_ReadByte(IIC1);
    I2C_Ack(IIC1,NO);
    I2C_Stop(IIC1);
    return 1;
}
